AROS
The Amiga Replacement OS
(C) 1996 AROS - The Amiga Replacement OS
Yeah, there are some things which are not in this archive for this or that reason. Here we go:
- Linux 2.0 or better for Intel CPUs (1.2.13 might work, but I haven't tried and won't do it).
- GNU make 3.74 or better - A real make is neccessary and this is one (use "make --version" to find out which you have).
- GCC 2.7.0 or better (2.7.2 is recommended because of the magnitude of bugs fixed) (use "gcc --version" to find out which you have).
- GAS/as from binutils 2.7 or better.
- GDB, the GNU debugger. It is no great help in our project because we do nasty things with the stack, but better than nothing anyway.
- GAWK to generate a couple of files (I have 3.0.0, but any version should work).
There are a couple of files and directories below AROS and here is a short overview of what they are and what you can do with them.
The root directory of AROS contains this:
- AFD-COPYRIGHT
-
AROS' copyright message
- BUGS
-
Known bugs of AROS
- README
-
A readme with a short introduction about AROS
- amiga/
-
This is the directory where you can (and should) put things which are copyrighted by someone and thus now part of the archive; right now this means only the amiga header files which you get along with your C-Compiler (eg. DICE, SAS/C, StormC++, Maxon C++) or from the Amiga Developer CD 1.1 (recommended since it's the most simple and inexpensive way to get them). The CD is available at your local dealer or by mail order. Just put the includes into a subdir include/below this directory and AROS will find them there.
- apps/
-
This directory contains the source for applications for AROS. Applications are programs and packages which are not in the basic installation which is in workbench/.
- compiler/
-
The C compiler for AROS. It contains include files, the source for amiga.lib and c.lib and the source for the compiler and all compiler specific utilities.
- arosshell.c
-
The main code for the shell which allows you to execute AROS commands as you are used to it on your beloved Amiga. Also a very small demo of how it works and also probably the smallest demo that does something useful.
- bin/
-
This directory contains all generated files under the name of your OS (eg. AROS/bin/linux/). This directory is called $(ARCHDIR). Below this are two more directories: $(BINDIR) where the files should be put which the end user should see and $(GENDIR) where you can create a directory to put all files one part of AROS needs (eg. libs/or os/). The directory $(OSGENDIR) is below $(GENDIR) and all *.ofiles in this directory are collected to the AmigaOS.lib.
- compiler/
-
The C compiler for AROS. It contains include files, the source for amiga.lib and c.lib and the source for the compiler and all compiler specific utilities.
- alib/
-
The source for the amiga.lib. This link library contains small utility functions which didn't made it into a shared library.
- aros/
-
The source for aros.lib. This link library contains special functions which allow to write portable code.
- clib/
-
The source for AROS' c.lib. This link library contains the standard ANSI C (and some more) library functions like printf(), strcpy(), etc.
The directory also contains the includes for ANSI C.
- include/
-
This directory contains all AROS specific includes as well as all Amiga includes which have been modified for AROS. Note that these files are searched *before* the files in amiga/include/. Most people will notice this when they compile some program which uses a function which has not yet been implemented in AROS. The compiler will complain about a function without a prototype despite the fact that it is in amiga/include/clib/*_protos.h. That's because it doesn't look there and if you ever get an error like this, have a look into include first.
- vbcc/
-
The source for AROS' own C compiler (not that we own it, but this compiler is used inside the AROS shell to compile programs).
- vcpp/
-
The source for the C preprocessor for AROS' C compiler.
- config/
-
This directory contains the dirty stuff. Code which makes AROS live (mostly hacked up assembler code which you don't want to see). Anything is allowed inside this directory in order to make AROS work on as many hardwares as possible.
- amiga/
-
Code to make AROS work on the Amiga itself. Currently the emulation is nonexistent, but we work on boot code (found in boot/).
- config.h
-
This is a generated include file. It's generated by AROS/configureand will appear in the include tree as aros/config.h. The following information can be found in this file:
- AROS_FLAVOUR
-
What version of AROS should be generated ? A native (binary compatible) one (AROS_FLAVOUR_NATIVE) ? A standalone OS (AROS_FLAVOUR_STANDALONE) ? An emulation which runs under another OS (AROS_FLAVOUR_EMULATION) ? A link library which allows to link native applications (ie. ones which behave like any other app on another OS) (AROS_FLAVOUR_LINKLIB) ?
Note that not all flavours are available on all hardwares/OS combinations. To use this #define, write something like #if AROS_FLAVOUR==AROS_FLAVOUR_NATIVE.
- dummy/
-
C source for kernel functions. These will not produce correct code to compile the kernel but when you compile and disassemble these, you will have a good starting point to write the assembler functions for the kernel.
- freebsd/
-
Code to make AROS work as an emulation under FreeBSD.
- host.cfg
-
This file is included by all makefiles and generated by AROS/configure. It defines the following Make variables:
- $(APP_CFLAGS)
-
Flags which replace $(COMMON_CFLAGS) when code for inside the AROS shell is to be compiled (not linked).
- $(ARCH)
-
What kind of OS is this ? Values are for example linux, freebsd, hpux, netbsd, amiga, etc.
- $(COMMON_AFLAGS)
-
Flags which must always be passed to $(AS).
- $(COMMON_CFLAGS)
-
Flags, which must always appear in $(CFLAGS) for $(CC).
- $(FLAVOUR)
-
What flavour of AROS should be generated ? The possible values are native, standalone, emulation or linklib.
- $(GUI_CCFLAGS)
-
Flags, which must be passed to $(CC) when code is to be compiled which uses the native GUI (eg. -I/usr/X11R6/include).
- $(GUI_INCDIR)
-
Directory where the include files for the native GUI can be found.
- $(GUI_LIBDIR)
-
Directory where link libraries for the GUI of the native OS can be found (eg. /usr/X11R6/lib).
- $(GUI_LIBFLAGS)
-
Libraries against which to link if you need the native GUI (eg. -lX11).
- $(GUI_LDFLAGS)
-
Flags, which must be passed to the linker when linking code which requires the native GUI (eg. the kernel or applications for flavour linklib).
- $(ILDFLAGS)
-
Flags which must be passed to $(CC) when code is to be linked for use in the AROS shell.
- $(KERNEL)
-
What kind of CPU is this ? Possible values are for example m68k-native, m68k-emul, i386, hppa9, etc.
- $(MKDEPEND)
-
Program to be called when Make wants to find out which include files should be taken into account when it's time to decide if a file must be updated or not (eg. makedepend).
- $(RANLIB)
-
Program to run on link libraries created with $(AR). Most of the time this will either be ranlibor true.
- $(SYS_AS)
-
The name of the systems' assembler. You should not use this value but the context sensitive $(AS) which contains the assembler to use in the current context.
- $(SYS_CC)
-
The name of the systems' C compiler. This may be different from $(CC), because $(CC) is context dependent (eg. if you compile code in the AROS shell, it's value is different from when you compile AROS kernel code).
- i386/
-
Version of the kernel for i386 CPUs. It consists mainly of a bunch of assembler files which implement functions that can't be done in C (eg. semaphores, stack handling or task switching). Note that this is the only directory which may contain assembler files and which is different for every architecture. If you begin your work on some new architecture, make such a directory for your hardware and put all hardware dependent files in there. It is a rule that you can do anything inside this directory as long as it has no influence on the other files and directories. The directory must support the standard rules all and clean and read AROS/config/make.cfg. All files generated by the makefile should go into $(OSGENDIR).
- init.c
-
This file contains the real main() and sets up all libraries, devices and all other stuff which must be known before the first user process can begin to work.
- machine.h
-
Constants which allow Exec to adjust to the local hardware.
- makefile
-
This is a good example of how sub-makefiles for AROS should look like.
- linux/
-
- m68k-emul/
-
Untested assembler code for machines which have an 680x0 CPU but which are not Amigas (Mac, for example).
- m68k-native/
-
Assembler code for Amiga hardware.
- machine.h
-
Constants which allow Exec to adjust to the local hardware.
- machine.c
-
- make.cfg
-
Global settings for the Makefiles. Each makefile reads this file before it does anything else (well, almost... most makefiles set a path to this file first :-) ) It sets up some interesting paths:
- $(OSGENDIR)
-
Use this path for all files which should go into the OS itself.
- configure
-
This is a small script which examines your system and creates a file named AROS/config/host.cfgwhich is used by the makefiles.
- crypt.c
-
This is a small program which allows you to create a password if you want to use the CVS server (prefered). See the section about CVS for how it works.
- dist/
-
make dist will put an archive with all files for developers and users in this directory. Make sure the version in make.cfg is set to the correct value because it will be used to determine the name of the archive.
- docs/
-
The source and the formatted docs (currently only in HTML format).
- makefile
-
This is the magic file which holds the whole thing together. It has the following rules:
This is the toplevel makefile. Use it if you want to compile the whole distribution.
This makefile defines the following targets:
- all
-
Compile the whole project (except the documentation).
- crypt
-
Create the file crypt to create a password for CVS access
- dist
-
Create the distribution archives
- check
-
Run tests to check if AROS runs ok on your system.
- clean
-
Remove all generated files
- cleandep
-
Remove all generated dependency files.
- docs
-
Compile the documentation for AROS.
- make.defaults
-
File with options for the make. If you want to change an option, create a file make.optsand put your changes there. The most simple method is just to copy make.defaultsto make.opts.
- rom/
-
Things which are internal parts of the OS.
- devs/
-
ROM devices, ie. devices which are not loaded from disk during runtime (eg. console.device).
- filesys/
-
A starting filesystem which uses the Linux filesystem to emulate a SYS:.
- dos/
-
The first library which is added to the OS by standard operations. Use this one as a starting point if you want to develop own libraries. Below is a list of interesting files.
All other files are functions of the library with one function per file. Each file contains an AutoDoc-like header and some extra infos which are needed by the scripts. If possible each file should also contain a test which can be enabled with -DTEST. See AROS/dos/filepart.cfor a good example.
- dos_functable.c
-
An array with all functions of the library. It is generated by a script from the headers of all *.c-files in this directory.
- dos_init.c
-
The init-code ( lib_init(), lib_open(), lib_close(), lib_expunge()).
- dos_intern.h
-
A common include-file for all *.c-files in this directory. It must not contain anything which is necessary outside this directory.
- dos_debug.h
-
Enable and disable debugging for a function of the library.
- makefile
-
This is a good example of how a makefile for a library, which is linked into the system, should look like
- exec/
-
The source for the exec.library. This is no good starting point for own libraries since Exec is not initialized like other libraries and so some things are handled differently here.
Exec relies on some files which are in $(KERNEL)/.
- graphics/
-
Sourcecode for the graphics.library. See dos/ for more information.
- intuition/
-
Sourcecode for the intuition.library. See dos/ for more information.
- utility/
-
Sourcecode for the utility.library. See dos/ for more information.
- scripts/
-
Scripts which are used to generate code.
- purify
-
A small script which can be put in front of the C compiler like this:
purify cc ...
It will modify some options to purify the code.
- test/
-
Testcode, which is more complex.
- tpl.c
-
Template file for AROS system library functions. Each function gets it's own file.
- workbench/
-
The disk-based part of AROS.
- c/
-
This directory contains a couple of applications for AROS and some demos.
- demos/
-
Some demos for AROS (former tests).
- devs/
-
Disk-based devices, eg. RAM:and NIL:.
- libs/
-
Disk-based shared libraries.
- locale/
-
Localization information. Languages, catalogs, country data.
- s/
-
This directory contains the Startup-Sequence.
This code is used by many people and therefore you should keep some things in mind when you submit source code:
- Keep things simple
- Keep the source clean
- Always know what you are doing
- Tell what you are doing
AROS uses some of the comments in the source to generate the documentation. Therefore it's neccessary to keep a certain format so the tools can find their information. Other comments are ignored but they should explain what you thought when you wrote the code. If you really can't think of an explanation, then don't write the code a second time like this:
/* This adds 1 to t */
t ++;
What we think of is this:
/* Go on with next element */
t ++;
Every function in AROS must have a full ANSI C prototype. Prototypes should be collected in in one header per file if it is needed by only a few files (no need to recompile the whole project if you change a function which used only once), in one header per directory if it's a commonly used function in that directory or in one header per logical group (ie. one header for all functions in a library).
The function header (ie. the comment before the function) must be of a special format because the AutoDocs are generated from it. Here is an example for it (from AROS/exec/addhead.c):
/*****************************************************************************
NAME */
#include <exec/lists.h>
#include <clib/exec_protos.h>
AROS_LH2I(void, AddHead,
/* SYNOPSIS */
AROS_LHA(struct List *, list, A0),
AROS_LHA(struct Node *, node, A1),
/* LOCATION */
struct ExecBase *, SysBase, 40, Exec)
/* FUNCTION
Insert Node node as the first node of the list.
INPUTS
list - The list to insert the node into
node - This node is to be inserted
RESULT
None.
NOTES
EXAMPLE
struct List * list;
struct Node * pred;
// Insert Node at top
AddHead (list, node);
BUGS
SEE ALSO
NewList(), AddTail(), Insert(), Remove(), RemHead(), RemTail(),
Enqueue()
INTERNALS
HISTORY
26-08-95 digulla created after EXEC-Routine
26-10-95 digulla adjusted to new calling scheme
******************************************************************************/
{
As you can see, comments are used to merge the function prototype and the header into one.
- NAME
-
This field contains all neccessary prototypes to use the function from the user point of view and the name of the function in a AROS_LH*() macro (Library Header). These macros are used to make the same code work on different kind of hardwares. The name of the macro depends on the amount of parameters and whether the function needs the library base. AddHead() does not and therefore an "I" is appended to the macros name. If it need the library base (like AddTask()), then the "I" is omitted.
If the function is not part of a shared library and it's arguments must be passed in certain registers (eg. callback hooks), you must use AROS_UFH*() macros (User Function Header) instead of AROS_LH*(). Append the number of arguments to this macro. Since it has never a base, the field LOCATION must be omitted and it's not neccessary to append the "I" to the macros name. An example for a callback hook foo() would be:
AROS_UFH3(ULONG, foo,
AROS_UFHA(struct Hook, hook, A0),
AROS_UFHA(APTR, obj, A2),
AROS_UFHA(APTR, param, A1)
)
(note that the registers need not have a particular order).
If the function is not part of a shared library and it's arguments need not be in specific registers, you need no AROS_*H*() macros:
/*****************************************************************************
NAME */
#include <header.h>
int foo (
/* SYNOPSIS */
int a,
int b)
/* FUNCTION
blahblahblah.
...
*****************************************************************************/
- SYNOPSIS
-
This field contains all arguments of the function one by one in AROS_LHA() macros (Library Header Argument). This macro makes sure the respective argument is put in the right CPU register when the function is called (if possible and neccessary). The first argument for the macro is the type of the parameter followed by the name of the parameter and the register the parameter is expected in. Valid names for registers are D0, D1, D2 upto D7 and A0 upto A6.
If the function is not part of a library but the arguments must be passed to it in registers, then use AROS_UFHA() macros (User Function Header Argument) which take the same parameters as the AROS_LHA() macros. Don't forget the closing parenthese for the AROS_UFC
If the function is not part of a library and the arguments need not be passed in registers, no macros are neccessary.
- LOCATION
-
This field is neccessary for shared libraries only. It contains the last four parameters for the AROS_LH*() macro which are the type of the library, the name of the variable, in which the function expects the library base, the offset of the function in the jumptable (the first vector has 1 and the first vector which may be used by a function is 5) and the name of the library.
- FUNCTION
-
This field contains a description of the function.
- INPUTS
-
This field contains a list of all parameters of the form "name - description" or "name, name, name - description". The description should tell what the parameter is and what values can be passed to it. There is no point in explaining the parameter twice in FUNCTION and here. If the function has no parameters, say "None." here.
- RESULT
-
What the function passes back. This includes return values and values passed in arguments of the function. If the function may fail, you should explain what it returns on failure and why it might fail.
- NOTES
-
Important things the user must know or take into account.
- EXAMPLE
-
This field should contain a small or fully featured example. A good way to present an example is to write some code which tests the function, put it into #ifdef TEST somewhere in the file and put a "See below." here. If you need comments in the code, you have two ways for this. If you need only short one-line comments, use C++ style ( //
comment). Everything from the // to the end if the line is the comment. If you need more comment, then you can end the comment after the EXAMPLE and use #ifdef EXAMPLE to mask the example out:
EXAMPLE */
#ifdef EXAMPLE
struct List * list;
struct Node * pred;
/* Insert Node at top of the list */
AddHead (list, node);
#endif
Don't use #ifdef EXAMPLE if you have a fully featured example (ie. one which can be compiled without errors).
- BUGS
-
This field contains a list of known bugs.
- SEE ALSO
-
This field contains a list of other functions and documents which might be of interest. This includes function which you need to initialize, create or destroy an object necessary for this function, functions which do similar and opposite things on the main object.
For example, SetAttrs() should contain functions here which can create, destroy and manipulate BOOPSI objects but not taglists.
- INTERNALS
-
This field should contain information for other developers which are irrelevant to the user, for example an explanation of the algorithm of the function or dependencies.
- HISTORY
-
This field should contain a brief history of changes. The format is date (DD-MM-YY), acronym (one word) and description.
Here is an example of how to format AROS code:
{
/* a */
struct RastPort * rp;
int a;
/* b */
rp = NULL;
a = 1;
/* c */
if (a == 1)
printf ("Init worked\n");
/* d */
if
(
!(rp = Get_a_pointer_to_the_RastPort
(
some,
long,
arguments
)
)
||
a <= 0
)
{
printf ("Something failed\n");
return FAIL;
}
/* e */
a = printf ("My RastPort is %p, a=%d\n"
, rp
, a
);
return OK;
}
Looks ugly, eh ? :-)
Ok, here are the rules:
- If several lines contain similar code, put similar things below each other (see a and b);
- Put spaces between operands and operators
- Put braces{}, brackets [] and parenthese () below each other (d) if there is much code between. Brackets and parenthese may be in one line if the code between is small (c)
- Indent by 4 Spaces. Two indent levels may be abbreviated by one tab.
- If you have a function with many arguments (d, e) you should put the parenthese in lines of their own and each argument in one line (d) or put the first argument behind the opening parenthese (e) and each following argument in a line of its own with the comma in front. The closing parenthese is in a line of its own and aligned with the beginning of the expression (ie. the a and not the opening parenthese or the printf()).
- use a single blank line to separate logical blocks. Large comments should have a blank line before and after them, small comments should be put before the code they explain with only one blank line before them.
prev
up
next
If you have comments or suggestions, email me at
digulla@aros.fh-konstanz.de.
13. Aug 1997